package com.flyqiu.flow.model.format.flowable;

import com.alibaba.fastjson2.JSONObject;
import org.dom4j.Attribute;
import org.dom4j.Element;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class FlowableUserTaskFormat extends DefaultFlowableElementFormat {

    @Override
    public String xmlElementType() {
        return "userTask";
    }


    @Override
    protected void elementToJson(Element element, List<Attribute> unProcessedAttrs, Map<String, Attribute> elementAttrMap, JSONObject result) {
        Element multiInstance = element.element("multiInstanceLoopCharacteristics");
        if (multiInstance == null) {
            super.elementToJson(element, unProcessedAttrs, elementAttrMap, result);
            return;
        }
        List<Element> elements = element.elements().stream().filter(e -> !e.equals(multiInstance)).collect(Collectors.toList());
        elementsToJson(elements, result);
        JSONObject multiInstanceJson = new JSONObject();
        Attribute sequential = element.attribute("isSequential");
        boolean isSequentialVal = false;
        if (sequential != null) {
            isSequentialVal = "true".equals(sequential.getValue());
        }
        multiInstanceJson.put("isSequential", isSequentialVal);
        elementToScriptJson(multiInstance, "loopCardinality", multiInstanceJson, "instanceNumScript");
        elementToScriptJson(multiInstance, "completionCondition", multiInstanceJson, "completeConditionScript");
        result.put("multiInstance", multiInstanceJson);
    }

    private void elementToScriptJson(Element element, String elementType, JSONObject parent, String jsonKey) {
        JSONObject script = new JSONObject();
        Element completionCondition = element.element(elementType);
        script.put("scriptExpression", completionCondition.getText());
        parent.put(jsonKey, script);
    }

    @Override
    protected void jsonToElement(JSONObject jsonElement, Set<String> unProcessedKeys, Element srcElement) {
        if (!jsonElement.containsKey("multiInstance")) {
            super.jsonToElement(jsonElement, unProcessedKeys, srcElement);
            return;
        }

        JSONObject multiInstanceJson = jsonElement.getJSONObject("multiInstance");
        unProcessedKeys.remove("multiInstance");
        super.jsonToElement(jsonElement, unProcessedKeys, srcElement);


        boolean isSequential = multiInstanceJson.getBooleanValue("isSequential", false);
        Element multiInstanceElement = srcElement.addElement("bpmn2:multiInstanceLoopCharacteristics");
        multiInstanceElement.addAttribute("isSequential", String.valueOf(isSequential));

        jsonToScriptElement(multiInstanceElement, "bpmn2:loopCardinality", multiInstanceJson, "instanceNumScript");
        jsonToScriptElement(multiInstanceElement, "bpmn2:completionCondition", multiInstanceJson, "completeConditionScript");
    }


    private void jsonToScriptElement(Element parent, String elementType, JSONObject json, String jsonKey) {
        JSONObject instanceNumScript = json.getJSONObject(jsonKey);
        Element element = parent.addElement(elementType);
        element.addAttribute("xsi:type", "bpmn2:tFormalExpression");
        element.addText(instanceNumScript.getString("scriptExpression"));
    }
}
